import {defineStore} from "pinia";
import {audioAnalogy, AxiosService, creatTrack} from '@/core'
import {formatDuring, isType} from "@/helper";
import ca from "../../../../dist/assets/system.eb229fca";

const axios = new AxiosService('netEasyMusic')
export declare interface PlayList{
    id:number,
    path:string,
    title:string,
    singer?:any[],
    totalTime:string | number,
    cover?:string,
}
export default defineStore({
    id:'netEasyMusic',
    state: ():{[key:string]:any} => ({
        navName:'findMusic', // 侧边导航层级
        pageRoute:'', // 实际展现页面
        router:[], // 陆游历史列表
        query:{}, // 页面切换query
        showDetail: false, // 展示歌曲详情
        analogyData:[], // 频谱数据
        pages:{ // 页面列表
            findMusic: [
                { name:'精选', value: 'recommend' },
                { name:'歌单', value: 'playlist' },
                { name:'排行榜', value: 'rank' },
                { name:'歌手', value: 'singer' },
                { name:'最新音乐', value: 'newMusic' },
            ],
            myFM:[
                { name:'我的电台', value:'myFM' }
            ],
            video:[
                { name:'视频',value:'video' },
                { name:'MV',value:'mv' }
            ],
            subscript:[
                { name:'我的订阅', value:'subscript' }
            ]
        },
        player:null, // 播放器实例
        playList:[], // 播放列表
        showPlayList:false, // 显示播放列表
        playing:{ // 正在播放的歌曲数据信息
            id:null,
            title:'-', // 标题
            cover:'', // 封面
            totalTime: '-', // 总时间 -- 实时计算
            currentTime: '-', // 当前时间 -- 实时计算
            isPlay:false, // 正在播放
        },
        setting:{
            lyric:{ // 歌词设置
                show:false,
                color:'',
                fontSize:'',
                id: null, // 歌曲id 作为校验是否需要重新加载,
                list: [], // 歌词拆分列表 []
                translateList:[], // 翻译列表
                origin:'',// 歌词原始数据
                now: null, // 正在播放的歌词 []
            },
            volume:0.5, // 音量
            loop:0, // 循环模式 0:顺序播放 1:单曲循环 2:列表循环 3:随机播放
        }
    }),
    actions:{
        changeNav(navName:string){
            this.$state.navName = navName
        },
        /** 压栈路由 */
        pushRouter(componentName:string,query:any = null){
            this.$state.query = query // 设置参数
            this.$state.router.push({componentName,query}) // 压栈
            this.$state.pageRoute = componentName
        },
        /** 出栈路由 */
        popRouter(){
            const { componentName,query } = this.$state.router.pop()
            this.$state.query = query // 设置参数
            this.$state.pageRoute = componentName
        },
        /** 获取路由名称 */
        getNavList(navName:string){
            return this.$state.pages[navName]
        },
        /** 切换循环模式 */
        changeLoop(){
            this.$state.setting.loop++
            if(this.$state.setting.loop > 3) this.$state.setting.loop = 0
        },
        /** 设置列表 */
        setPlayList(ids:number[] | string[] | number | string, clear:boolean = false, play:boolean = true, cursor:string = 'next'){
            return new Promise<void>(async (resolve,reject) => {
                let id:string = ''
                //todo 单曲播放形式
                if(isType(ids,'string') || isType(ids,'number'))  {
                    id = String(ids)
                    const hasId =  this.$state.playList.findIndex((ele:any) => String(ele?.id) === String(id))
                    if(hasId !== -1) { // 列表包含当前歌曲
                        this.setMusic( this.$state.playList?.[hasId])
                        return resolve()
                    }
                }
                //todo 数组列表形式
                // @ts-ignore
                else if((isType(ids,'array') && ids.length)) id = ids.reduce(( total:string, pre: number | string, index:number) => total + (index === 0 ? '' : ',') + pre ,'') // 去重数组 如果当前id已有则不加入
                if(!id) return reject() // 识别错误拒绝
                let list: any[] = [] // 生成数组
                await axios.get({ // 获取歌曲详情
                    api:'/song/detail',
                    params:{ids:id},
                    success: ({songs}) => list = songs.map((ele:any) => ({
                        ...ele,
                        path: `/netEasyMusicLink/song/media/outer/url?id=${ele.id}.mp3`,
                        cover: ele?.al?.picUrl, // 图片
                        title: ele.name, // 标题
                    }))
                })
                if(clear) { // 优先级最高
                    this.$state.playList = list
                    this.$state.playing.id = null // 清空id 下一曲播放不寻找并定位第一首
                    this.nextMusic()
                    return resolve()
                }
                list = list.filter((ele:any) => this.$state.playList.findIndex((item:any) => String(item?.id) === String(ele?.id)) === -1) // 非清除插入列表模式，去重原列表相同id项
                switch(cursor){
                    case 'next' :{ // 添加列表方式 一般采用next 当前播放的下一个
                        const idx = this.$state.playList.findIndex((ele:any) => ele?.id === this.$state.playing?.id)
                        this.$state.playList.splice(idx + 1,0,...list)
                        break
                    }
                    case 'last' :{
                        this.$state.playList = [...this.$state.playList, ...list]
                        break
                    }
                    case 'top' :{
                        this.$state.playList = [...list,...this.$state.playList]
                        break
                    }
                }
                if(play) this.nextMusic(!isType(ids,'array'))
                resolve()
            })
        },
        /** 通过歌单id设置歌曲 */
        setPlayListById(playListId:number | string, clear:boolean = true,play:boolean = true,cursor:string = 'next'){
            return new Promise<void>(async (resolve,reject) => {
            await axios.get({
                api:'/playlist/track/all',
                params:{id:playListId},
                success: ({songs}) => this.setPlayList(songs.map((ele:any) => ele.id),clear,play,cursor)
            })
                resolve()
            })
        },
        /** 初始化播放器 */
        initPlayer(){
            return new Promise<void>((resolve,reject)=>{
                if (this.$state.player) return resolve()
                this.$state.player = new creatTrack(null,this.$state.setting.volume,false)
                this.$state.player.handleTimeUpdate((res: { currentTime: any; duration: any; }) => { // 设置时间回调
                    const { currentTime, duration } = res
                    this.$state.playing.totalTime = formatDuring(duration,'{m}:{s}')
                    this.$state.playing.currentTime = formatDuring(currentTime,'{m}:{s}')
                    const findIndex = this.$state.setting.lyric.list.findIndex((ele:any) => ele.time === parseInt(currentTime))
                    this.$state.setting.lyric.now =  findIndex >= 0 ? findIndex : this.$state.setting.lyric.now
                })
                this.$state.player.handleStateChange((res: { type: any; }) => { // 设置时间回调
                    const { type } = res
                    this.$state.playing.isPlay = type === 'play'
                    if(type === 'ended') {
                        if(this.$state.setting.loop === 1){
                            this.setTime('0:0')
                            this.togglePlay(true)
                        }
                        else this.nextMusic()
                    }
                    if(type === 'error') this.nextMusic()
                    if(type === 'play') this.setLyric()
                })
                audioAnalogy(this.$state.player.analogyNode, (res:ArrayBuffer) => this.$state.analogyData = res)
                return resolve()
            })
        },
        /** 上一首 */
        async preMusic(){
            return new Promise<void>(async (resolve,reject) => {
                if(!this.$state.playList.length) return resolve() // 无播放列表
                const findIndex = this.$state.playList.findIndex((item: { id: any; }) => item.id === this.$state.playing.id)
                if(findIndex === -1 || findIndex === 0) return  resolve() // 未找到当前音乐
                const item = this.$state.playList?.[findIndex - 1]
                await this.setMusic(item)
                return  resolve() // 正常加载
            })
        },
        /** 切换播放暂停 */
        async togglePlay(forcePlay = false){
            if(!isType(forcePlay,'Boolean')) forcePlay = false
            if(this.$state.playing.isPlay && !forcePlay) this.$state.player.pause() // 如果是播放则变成暂停
            else{ // 如果是暂停需要检测当前是否有加载的音轨
                const { id } = this.$state.playing
                if(!id) return await this.nextMusic()
                this.$state.player.play()
            }
        },
        /** 下一曲 */
        async nextMusic(forceNext:boolean = false){
            return new Promise<void>(async (resolve,reject) => {
                if(!this.$state.playList.length) return resolve() // 无播放列表不允许播放
                const findIndex = this.$state.playList.findIndex((item: { id: string | number }) => item.id === this.$state.playing.id)
                let item:any = {}
                switch (forceNext ? 2 :this.$state.setting.loop){
                    case 2 :{ // 列表循环
                        if(findIndex === this.$state.playList.length - 1) item = this.$state.playList?.[0]
                        else item = this.$state.playList?.[ findIndex + 1]
                        break
                    }
                    case 3 :{ // 随机播放
                        const randomIndex = Math.floor(Math.random() * this.$state.playList.length)
                        item = this.$state.playList?.[randomIndex]
                        break
                    }
                    default :{
                        if(findIndex === this.$state.playList.length - 1) return resolve() // 最后一首停止播放
                        else item = this.$state.playList?.[ findIndex + 1]
                        break
                    }
                }
                await this.setMusic(item)
                return resolve()
            })
        },
        /** 设置音乐 */
        async setMusic(item:any){
            const { id } = item
            if(id === this.$state.playing?.id) return
            await this.initPlayer()
            this.$state.playing = item
            this.$state.player.setMusic(item.path)
            this.togglePlay(true)
        },
        /** 改变音量 */
        changeVolume(value:number){
            this.$state.setting.volume = value
            if(!this.$state.player) return
            this.$state.player.setGain(value)
        },
        /** 设置时间 */
        setTime(time:string){
            const [minute,second] = time.split(':').map((item: any) => Number(item))
            const value =  (minute * 60 + second)
            this.$state.player.setCurrentTime(value)
        },
        /** 绑定歌词 */
        setLyric(){
            const { id } = this.$state.playing
            const { id:hasId } = this.$state.setting?.lyric
            if(id === hasId) return
            this.$state.setting.lyric.id = id
            axios.get({
                api:'/lyric',
                params:{ id },
                success: res => {
                   const { lrc,tlyric } = res
                    const { lyric } = lrc
                    this.$state.setting.lyric.list = lyric.split('\n').map((ele: string) => ({
                        time: ele.match(/\[(.+?)\]/g)?.[0].replace(/[\[\]]/g, '').split(':')?.reduce((total: number, pre: string, index: number) => total += parseInt(pre) * (index === 0 ? 60 : 1), 0),
                        value: ele.replace(/\[(.+?)\]/g, '')
                    }))
                    this.$state.setting.lyric.origin = res
                }
            })
        },
        /** 切换展示详情 */
        toggleShowDetail(){
          this.$state.showDetail = !this.$state.showDetail
        },
        /** 控制显示播放列表 */
        setShowPlayList(sign:boolean){
            this.$state.showPlayList = sign
        },
    }
})()
